package  
{
	import org.flixel.*;
	
	public class Death extends FlxSprite
	{
		private static const MIN_DIST:int = 260;
		
		private var _playState:PlayState;
		private var _initialX:int;
		private var _initialY:int;
		private var _totalTime:Number;
		private var _chillTime:Number;
		private var _target:Human;
		private var _distanceToTarget:Number = -1;
		
		public function Death(playState:PlayState):void
		{
			super(0, 0, AssetManager.GrimReaper);
			_playState = playState;
			_totalTime = 0;
			this.x = 20;
			this.y = FlxG.height - ConfigData.GROUND_HEIGHT - this.height - 4;
			this.alpha = .8;
			this._initialX = x;
			this._initialY = y;
		}
		
		private function findBestTarget():Human
		{
			var bestHum:Human = null;
			var count:int = _playState.humans.members.length;
			for (var i:int = 0; i < count; i++)
			{	
				if (_playState.humans.members[i] == null)
				{
					continue;
				}
				var hum:Human = _playState.humans.members[i];
				if (bestHum == null)
				{
					bestHum = hum;
				}
				else
				{
					var bestAge:int = Math.floor(bestHum.getAge());
					var thisAge:int = Math.floor(hum.getAge());
					switch(thisAge)
					{
						case ConfigData.AGE_1_INFANT : 
							{
								if (bestAge != ConfigData.AGE_6_INVALID)
								{
									bestHum = hum;
								}
								break;
							}
						case ConfigData.AGE_2_TODDLER :
							{
								if (bestAge != ConfigData.AGE_6_INVALID && bestAge != ConfigData.AGE_1_INFANT)
								{
									bestHum = hum;
								}
								break;
							}
						case ConfigData.AGE_3_TEEN :
							{
								if (bestAge != ConfigData.AGE_6_INVALID && 
									bestAge != ConfigData.AGE_1_INFANT &&
									bestAge != ConfigData.AGE_2_TODDLER &&
									bestAge != ConfigData.AGE_5_OLD_ADULT)
								{
									bestHum = hum;
								}
								break;
							}
						case ConfigData.AGE_4_ADULT :
							{
								if (bestAge != ConfigData.AGE_6_INVALID && 
									bestAge != ConfigData.AGE_1_INFANT &&
									bestAge != ConfigData.AGE_2_TODDLER &&
									bestAge != ConfigData.AGE_5_OLD_ADULT && 
									bestAge != ConfigData.AGE_3_TEEN)
								{
									bestHum = hum;
								}
								break;
							}
						case ConfigData.AGE_5_OLD_ADULT :
							{
								if (bestAge != ConfigData.AGE_6_INVALID && 
									bestAge != ConfigData.AGE_1_INFANT &&
									bestAge != ConfigData.AGE_2_TODDLER)
								{
									bestHum = hum;
								}
								break;
							}
						case ConfigData.AGE_6_INVALID : 
							{
								bestHum = hum;
								break;
							}
						case ConfigData.AGE_7_DEAD : break;
					}
				}
			}
			return bestHum;
		}
		
		private function getMaxVelocityForAge(age:Number):Number
		{
			switch(age)
			{
				case ConfigData.AGE_1_INFANT : return 30;
				case ConfigData.AGE_2_TODDLER : return 25;
				case ConfigData.AGE_3_TEEN : return 10;
				case ConfigData.AGE_4_ADULT : return 10;
				case ConfigData.AGE_5_OLD_ADULT : return 25;
				case ConfigData.AGE_6_INVALID : return 30;
				case ConfigData.AGE_7_DEAD : return 20;
			}
			return 20;
		}
		
		private function getAccelerationForAge(age:Number):Number
		{
			switch(age)
			{
				case ConfigData.AGE_1_INFANT : return 20;
				case ConfigData.AGE_2_TODDLER : return 15;
				case ConfigData.AGE_3_TEEN : return 10;
				case ConfigData.AGE_4_ADULT : return 10;
				case ConfigData.AGE_5_OLD_ADULT : return 15;
				case ConfigData.AGE_6_INVALID : return 20;
				case ConfigData.AGE_7_DEAD : return 20;
			}
			return 20;
		}
		
		private function lerpForAge(age:Number, low:Number, high:Number):Number
		{
			var percent:Number = age - Math.floor(age);
			return (low + (high - low) * percent);
		}
		
		private function killHumans():void
		{
			var toKill:Array = new Array();
			for (var i:int = 0; i < _playState.humans.members.length; i++)
			{	
				if (_playState.humans.members[i] == null)
				{
					continue;
				}
				var hum:Human = _playState.humans.members[i];
				var midPt:FlxPoint = this.getMidpoint();
				var targetPt:FlxPoint = hum.getMidpoint();
				var distToTarget:Number = targetPt.x - midPt.x;
				if (Math.abs(distToTarget) < this.width)
				{
					toKill.push(hum);
				}
			}
			for (var j:int = 0; j < toKill.length; j++)
			{
				toKill[j].killHuman();
				_chillTime = 4;
			}
		}
		
		public function get distanceToTarget():Number
		{
			return _distanceToTarget;
		}
		
		public function get target():Human
		{
			return _target;
		}
		
		public override function update():void
		{
			
			_totalTime += FlxG.elapsed;
			if (_chillTime > 0)
			{
				_chillTime -= FlxG.elapsed;
				if (_chillTime < 0)
				{
					_chillTime = 0;
				}
			}
			var sinVal:Number = Math.sin(_totalTime) * 4;
			this.y = _initialY + int(sinVal);
			if (_chillTime > 0)
			{
				this.velocity.x = 0;
			}
			else 
			{
				_target = findBestTarget();
				if (_target != null)
				{
					var midPt:FlxPoint = this.getMidpoint();
					var targetPt:FlxPoint = _target.getMidpoint();
					var distanceToTarget:Number = targetPt.x - midPt.x;
					var accel:Number = 0;
					if (Math.abs(distanceToTarget) > MIN_DIST)
					{
						accel = 100;
					}
					else
					{
						accel = lerpForAge(_target.getAge(), getAccelerationForAge(_target.getAgeFloored()), getAccelerationForAge(Math.ceil(_target.getAge())));
					}
					if (distanceToTarget < 0)
					{
						accel *= -1;
					}
					this.acceleration.x = accel;
					if (Math.abs(distanceToTarget) < MIN_DIST)
					{
						var maxVelocity:Number = lerpForAge(_target.getAge(), getMaxVelocityForAge(_target.getAgeFloored()), getMaxVelocityForAge(Math.ceil(_target.getAge())));
						if (this.velocity.x > maxVelocity)
						{
							this.velocity.x = maxVelocity;
						}
						else if (this.velocity.x < -maxVelocity)
						{
							this.velocity.x = -maxVelocity;
						}
					}
					_distanceToTarget = distanceToTarget;
				}
				else 
				{
					this.acceleration.x = 15;
					distanceToTarget = -1;
				}
			}
			killHumans();
		}
	}
}